package com.vhall.component.plugin.common.aspect;

import com.alibaba.fastjson.JSON;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.VssToken;
import com.vhall.component.plugin.common.support.VssTokenThreadLocal;
import com.vhall.component.plugin.common.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * Vss Token 获取切面
 *
 * @author yongzheng.xu
 * @date 2021/6/20 19:27
 */
@Slf4j
@Aspect
@Component
public class VssTokenAspect extends BaseDataAspect {


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Pointcut("@annotation(com.vhall.component.plugin.common.annotation.VssTokenAuth)|| @within(com.vhall.component.plugin.common.annotation.VssTokenAuth)")
    public void pointCut() {
        // Do nothing
    }

    @Around("pointCut()")
    public Object vssTokenBefore(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        Assert.notNull(servletRequestAttributes, "请求参数异常");
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String param = request.getHeader("vsstoken");

        VssToken tk;
        String tokenText = "";
        if (validMockFlag(request)) {
            tokenText = "{\"expire_time\":\"2023-04-26 14:19:35\",\"app_id\":\"TVB9THkQ\",\"third_party_user_id\":9079}";
        } else {
            if (StringUtils.isAllEmpty(param)) {
                throw new BusinessException(BizErrorCode.AUTH_VSS_TOKEN_INVALID);
            }

            String token = redisTemplate.opsForValue().get(param);
            if (StringUtils.isBlank(token)) {
                throw new BusinessException(BizErrorCode.AUTH_VSS_TOKEN_EXPIRE);
            }
            tokenText = JSON.parse(token).toString();
        }
        try {
            tk = JsonUtil.objectFromJSONString(tokenText, VssToken.class);
            VssTokenThreadLocal.setToken(tk);
            return joinPoint.proceed(args);
        } catch (Throwable e) {
            log.error("", e);
            throw e;
        } finally {
            VssTokenThreadLocal.remove();
        }
    }
}
